<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="rdipS" id="rdipS"><span data-lake-id="u6f164b1a" id="u6f164b1a">典型回答</span></h1>
  <p data-lake-id="ubbc4118b" id="ubbc4118b"><br></p>
  <p data-lake-id="uf9f88b07" id="uf9f88b07"><span data-lake-id="u715d24da" id="u715d24da">字典锁，英文名叫做MetaData Lock，也叫做MDL锁，它是一种用于管理元数据的锁机制，而不是数据本身的锁。</span></p>
  <p data-lake-id="u1f5169a6" id="u1f5169a6"><span data-lake-id="ue5ac338e" id="ue5ac338e">​</span><br></p>
  <p data-lake-id="u33fb5892" id="u33fb5892"><span data-lake-id="uaf23f795" id="uaf23f795">MDL锁用于控制对数据库对象的元数据的并发访问，数据库会在执行DDL（Data Defination Language）操作时加上字典锁。字典锁的主要目的是保护数据库中的元数据对象，如表、列、索引、视图等，以确保在DDL操作期间，不会出现数据一致性问题和竞争条件。</span></p>
  <p data-lake-id="u22438bda" id="u22438bda"><span data-lake-id="u3a3336f0" id="u3a3336f0">​</span><br></p>
  <p data-lake-id="u82484bdc" id="u82484bdc"><span data-lake-id="ua57b5639" id="ua57b5639">以下是触发数据库加字典锁的一些情况：</span></p>
  <ol list="u66ab1a9a">
   <li fid="u50e63af4" data-lake-id="u54c48b0a" id="u54c48b0a"><strong><span data-lake-id="u7f56c4a2" id="u7f56c4a2">创建/修改/删除表结构</span></strong><span data-lake-id="u5986c79e" id="u5986c79e">：当执行CREATE TABLE、ALTER TABLE、DROP TABLE等DDL语句时，数据库会对相关的表和表的元数据对象加上字典锁，以阻止其他事务同时修改这些表的结构。</span></li>
   <li fid="u50e63af4" data-lake-id="u7f05f367" id="u7f05f367"><strong><span data-lake-id="u5c7a2757" id="u5c7a2757">创建/修改/删除索引</span></strong><span data-lake-id="u5946f1e8" id="u5946f1e8">：执行CREATE INDEX、ALTER TABLE 添加索引、修改、删除索引等DDL操作时，会锁定与索引相关的元数据，以确保索引的一致性。</span></li>
   <li fid="u50e63af4" data-lake-id="u871f0f28" id="u871f0f28"><strong><span data-lake-id="u0d528890" id="u0d528890">修改列定义</span></strong><span data-lake-id="u677630c5" id="u677630c5">：如果执行ALTER TABLE来修改表的列定义，例如改变数据类型、添加、删除、重命名列等，相关的列和表的元数据会被锁定。</span></li>
   <li fid="u50e63af4" data-lake-id="ud5a2907f" id="ud5a2907f"><strong><span data-lake-id="u75796c16" id="u75796c16">创建/修改/删除视图</span></strong><span data-lake-id="u3d7579f0" id="u3d7579f0">：当执行CREATE VIEW、ALTER VIEW、DROP VIEW等DDL操作以创建或修改视图时，相关视图的元数据会被锁定。</span></li>
   <li fid="u50e63af4" data-lake-id="u4d00a875" id="u4d00a875"><strong><span data-lake-id="u188efc1f" id="u188efc1f">其他DDL操作</span></strong><span data-lake-id="u3b19c434" id="u3b19c434">：其他的DDL操作，如创建、修改、删除存储过程、触发器、事件等也可能涉及到元数据的锁定。</span></li>
  </ol>
  <p data-lake-id="u51658a44" id="u51658a44"><span data-lake-id="ua710d817" id="ua710d817">​</span><br></p>
  <h1 data-lake-id="cOq4w" id="cOq4w"><span data-lake-id="uabd0e7e6" id="uabd0e7e6">扩展知识</span></h1>
  <p data-lake-id="ub02d3d46" id="ub02d3d46"><br></p>
  <h2 data-lake-id="oqywR" id="oqywR"><span data-lake-id="u37cbfb27" id="u37cbfb27">字典锁升级</span></h2>
  <p data-lake-id="u3f6d415f" id="u3f6d415f"><br></p>
  <p data-lake-id="u2c7e8e79" id="u2c7e8e79"><span data-lake-id="u2d7e96f7" id="u2d7e96f7">在数据库中，通常有两种主要的锁级别，即共享锁和排他锁，而字典锁也有两种级别，即：</span></p>
  <p data-lake-id="u93c7d16c" id="u93c7d16c"><span data-lake-id="ua5fe0c67" id="ua5fe0c67">​</span><br></p>
  <ol list="ua88803d9">
   <li fid="u1428a64f" data-lake-id="u6d68d617" id="u6d68d617"><span data-lake-id="u642ef170" id="u642ef170">共享字典锁（SHARED-MDL ）：这允许多个事务同时读取元数据对象，但不允许任何事务修改它们。共享字典锁通常用于保护元数据的读取操作，以确保在读取元数据时不会被其他事务修改。</span></li>
  </ol>
  <p data-lake-id="uea713b1f" id="uea713b1f"><br></p>
  <ol list="ua88803d9" start="2">
   <li fid="u1428a64f" data-lake-id="u3b87b37d" id="u3b87b37d"><span data-lake-id="u2060a369" id="u2060a369">排他字典锁（EXCLUSIVE-MDL ）：排他字典锁是最高级别的字典锁，它阻止其他事务同时读取或修改元数据对象。只有一个事务可以持有排他字典锁，通常用于保护元数据的写操作，以确保数据的完整性。</span></li>
  </ol>
  <p data-lake-id="u4e67738d" id="u4e67738d"><span data-lake-id="uc5f0a23d" id="uc5f0a23d"><br></span><span data-lake-id="u9bef9ef5" id="u9bef9ef5"> </span></p>
  <p data-lake-id="u2c55cd04" id="u2c55cd04"><span data-lake-id="u02579da2" id="u02579da2">而在字典锁的加锁过程中，会有升级的情况，当事务开始时，通常会以</span><strong><span data-lake-id="ud84050db" id="ud84050db">共享字典锁</span></strong><span data-lake-id="u052d9bc3" id="u052d9bc3">的方式访问元数据对象。这允许多个事务同时读取相同的元数据。</span></p>
  <p data-lake-id="u7435e25e" id="u7435e25e"><span data-lake-id="u1c085161" id="u1c085161">​</span><br></p>
  <p data-lake-id="u0c3479d4" id="u0c3479d4"><span data-lake-id="u5a4f4824" id="u5a4f4824">如果事务需要对元数据对象进行修改操作，例如修改表结构或索引，它需要将共享字典锁</span><u><span data-lake-id="ud4fd55fa" id="ud4fd55fa">升级</span></u><span data-lake-id="ufa39cb1b" id="ufa39cb1b">为</span><strong><span data-lake-id="uc8faa83a" id="uc8faa83a">排他字典锁</span></strong><span data-lake-id="u356a5247" id="u356a5247">，以阻止其他事务同时访问该元数据对象。</span></p>
  <p data-lake-id="u589b4440" id="u589b4440"><span data-lake-id="ua12ca9fc" id="ua12ca9fc">​</span><br></p>
  <p data-lake-id="u3c250fc6" id="u3c250fc6"><span data-lake-id="ua16c8f65" id="ua16c8f65">在数据库管理系统中，升级通常是自动执行的。当事务尝试修改元数据对象时，系统会检测到需要升级共享字典锁为排他字典锁，以确保数据的完整性。</span></p>
 </body>
</html>